import { connectToDatabase } from '../data/db.js'
import { COLLECTION_QUESTION, COLLECTION_QUESTION_COMPONENTS_LIST } from '../constant/dbConfig.js'
import { formatDate } from '../utils/index.js'
import { Result } from '../utils/result.js'
import { ObjectId } from 'mongodb'

const db = await connectToDatabase()
// 问卷列表实例
const questionCollection = await db.collection(COLLECTION_QUESTION)
// 组件列表的实例
const componentListCollection = await db.collection(COLLECTION_QUESTION_COMPONENTS_LIST)

export default [
  {
    // 查询列表
    url: '/api/question/list',
    method: 'get',
    response: async ctx => {
      let { title, isStar, isDelete = 0, pageNum = 1, pageSize = 10 } = ctx.query

      const query = {
        isDelete: isDelete === '1' ? 1 : 0,
        title: new RegExp(title || '', 'i')
      }
      if (isStar !== undefined) {
        query.star = { $eq: isStar === 'true' }
      }

      if (typeof pageNum === 'string') {
        pageNum = parseInt(pageNum)
      }
      if (typeof pageSize === 'string') {
        pageSize = parseInt(pageSize)
      }

      const skip = (pageNum - 1) * pageSize
      const limit = pageSize

      const result = await questionCollection.find(query).skip(skip).limit(limit).toArray()

      const total = await questionCollection.countDocuments(query)
      return Result.success({
        list: result,
        total
      })
    }
  },
  {
    // 新增
    url: '/api/question/add',
    method: 'post',
    response: async ctx => {
      // 组件列表必传
      if (!ctx.request.body.componentsList || ctx.request.body.componentsList.length === 0) {
        return Result.error().setMsg('组件列表不能为空')
      }
      const result = await questionCollection.insertOne({
        userId: ctx.state.user._id, // 当前用户的id
        createTime: formatDate(),
        isDelete: 0,
        title: ctx.request.body.title,
        publish: ctx.request.body.publish,
        star: ctx.request.body.star,
        description: ctx.request.body.description,
        jsCode: ctx.request.body.jsCode,
        cssCode: ctx.request.body.cssCode
      })
      // 拿到新增的问卷的id
      if (result.insertedId) {
        // 组装组件列表
        const componentsList = ctx.request.body.componentsList.map(comp => {
          if (comp._id) delete comp._id // 删除组件列表中的_id
          return {
            ...comp,
            questionId: result.insertedId.toString()
          }
        })
        // 组件列表插入到数据库
        await componentListCollection.insertMany(componentsList)
      }
      return Result.success(result)
    }
  },
  {
    // 根据ID获取详情
    url: '/api/question/getInfo',
    method: 'get',
    response: async ctx => {
      const { _id } = ctx.query
      // 获取问卷详情
      const result = await questionCollection.findOne({
        _id: new ObjectId(_id)
      })
      // 在根据问卷获取对应的组件列表
      result.componentsList = await componentListCollection
        .find({
          questionId: _id
        })
        .toArray()
      // 获取post参数
      return Result.success(result)
    }
  },
  {
    // 根据ID更新
    url: '/api/question/update',
    method: 'post',
    response: async ctx => {
      try {
        const {
          _id,
          title,
          publish,
          star,
          isDelete,
          description,
          jsCode,
          cssCode,
          componentsList = []
        } = ctx.request.body
        // 组装要更新的字段
        const updateFields = {}
        if (title !== undefined && title !== null) updateFields.title = title
        if (publish !== undefined && publish !== null) updateFields.publish = publish
        if (star !== undefined && star !== null) updateFields.star = star
        if (isDelete !== undefined && isDelete !== null) updateFields.isDelete = isDelete
        if (description !== undefined && description !== null)
          updateFields.description = description
        if (jsCode !== undefined && jsCode !== null) updateFields.jsCode = jsCode
        if (cssCode !== undefined && cssCode !== null) updateFields.cssCode = cssCode
        // 根据id更新问卷基本信息
        await questionCollection.updateOne({ _id: new ObjectId(_id) }, { $set: updateFields })
        // 先根据问卷id删除对应的组件列表
        await componentListCollection.deleteMany({
          questionId: _id
        })
        if (componentsList.length > 0) {
          // 再组件列表中插入新的数据
          const newComponentsList = componentsList.map(comp => {
            if (comp._id) delete comp._id // 删除组件列表中的_id
            return {
              ...comp,
              questionId: _id
            }
          })
          // 更新这个问卷对应的组件列表
          await componentListCollection.insertMany(newComponentsList)
        }

        // 查询更新后的数据
        const newInfo = await questionCollection.findOne({
          _id: new ObjectId(_id)
        })
        return Result.success(newInfo)
      } catch (error) {
        return Result.error(error)
      }
    }
  },
  {
    // 根据ID假删除
    url: '/api/question/delete',
    method: 'delete',
    response: async ctx => {
      const { _id } = ctx.query
      await questionCollection.updateOne({ _id: new ObjectId(_id) }, { $set: { isDelete: 1 } })
      return Result.success({
        _id
      })
    }
  },
  {
    // 批量还原
    url: '/api/question/restore',
    method: 'put',
    response: async ctx => {
      const { ids } = ctx.request.body
      // 得到要删除的id数组
      await questionCollection.updateMany(
        { _id: { $in: ids.map(id => new ObjectId(id)) } },
        { $set: { isDelete: 0 } }
      )
      return Result.success()
    }
  },
  {
    // 彻底删除
    url: '/api/question/remove',
    method: 'put',
    response: async ctx => {
      const { ids } = ctx.request.body
      // 得到要删除的id数组
      await questionCollection.deleteMany({
        _id: { $in: ids.map(id => new ObjectId(id)) }
      })
      return Result.success()
    }
  },
  {
    // 移动端根据问卷id获取组件列表
    url: '/h5/getComponentsList',
    method: 'get',
    response: async ctx => {
      try {
        const { _id } = ctx.query
        // 获取问卷详情
        const questionInfo = await questionCollection.findOne({
          _id: new ObjectId(_id)
        })
        const componentsList = await componentListCollection
          .find({
            questionId: _id
          })
          .toArray()
        return Result.success({
          ...questionInfo,
          componentsList
        })
      } catch (error) {
        return Result.error(error)
      }
    }
  }
]
